package com.fr.base.core.antlr.preprocessor;

import com.fr.base.core.antlr.ANTLRException;
import com.fr.base.core.antlr.TokenStreamException;
import com.fr.base.core.antlr.Tool;
import com.fr.base.core.antlr.collections.impl.IndexedVector;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Enumeration;
import java.util.Hashtable;

public class Hierarchy
{
  protected Grammar LexerRoot = null;
  protected Grammar ParserRoot = null;
  protected Grammar TreeParserRoot = null;
  protected Hashtable symbols;
  protected Hashtable files;
  protected Tool antlrTool;

  public Hierarchy(Tool paramTool)
  {
    this.antlrTool = paramTool;
    this.LexerRoot = new Grammar(paramTool, "Lexer", null, null);
    this.ParserRoot = new Grammar(paramTool, "Parser", null, null);
    this.TreeParserRoot = new Grammar(paramTool, "TreeParser", null, null);
    this.symbols = new Hashtable(10);
    this.files = new Hashtable(10);
    this.LexerRoot.setPredefined(true);
    this.ParserRoot.setPredefined(true);
    this.TreeParserRoot.setPredefined(true);
    this.symbols.put(this.LexerRoot.getName(), this.LexerRoot);
    this.symbols.put(this.ParserRoot.getName(), this.ParserRoot);
    this.symbols.put(this.TreeParserRoot.getName(), this.TreeParserRoot);
  }

  public void addGrammar(Grammar paramGrammar)
  {
    paramGrammar.setHierarchy(this);
    this.symbols.put(paramGrammar.getName(), paramGrammar);
    GrammarFile localGrammarFile = getFile(paramGrammar.getFileName());
    localGrammarFile.addGrammar(paramGrammar);
  }

  public void addGrammarFile(GrammarFile paramGrammarFile)
  {
    this.files.put(paramGrammarFile.getName(), paramGrammarFile);
  }

  public void expandGrammarsInFile(String paramString)
  {
    GrammarFile localGrammarFile = getFile(paramString);
    Enumeration localEnumeration = localGrammarFile.getGrammars().elements();
    while (localEnumeration.hasMoreElements())
    {
      Grammar localGrammar = (Grammar)localEnumeration.nextElement();
      localGrammar.expandInPlace();
    }
  }

  public Grammar findRoot(Grammar paramGrammar)
  {
    if (paramGrammar.getSuperGrammarName() == null)
      return paramGrammar;
    Grammar localGrammar = paramGrammar.getSuperGrammar();
    if (localGrammar == null)
      return paramGrammar;
    return findRoot(localGrammar);
  }

  public GrammarFile getFile(String paramString)
  {
    return ((GrammarFile)this.files.get(paramString));
  }

  public Grammar getGrammar(String paramString)
  {
    return ((Grammar)this.symbols.get(paramString));
  }

  public static String optionsToString(IndexedVector paramIndexedVector)
  {
    String str = "options {" + System.getProperty("line.separator");
    Enumeration localEnumeration = paramIndexedVector.elements();
    while (localEnumeration.hasMoreElements())
      str = str + ((Option)localEnumeration.nextElement()) + System.getProperty("line.separator");
    str = str + "}" + System.getProperty("line.separator") + System.getProperty("line.separator");
    return str;
  }

  public void readGrammarFile(String paramString)
    throws FileNotFoundException
  {
    BufferedReader localBufferedReader = new BufferedReader(new FileReader(paramString));
    addGrammarFile(new GrammarFile(this.antlrTool, paramString));
    PreprocessorLexer localPreprocessorLexer = new PreprocessorLexer(localBufferedReader);
    localPreprocessorLexer.setFilename(paramString);
    Preprocessor localPreprocessor = new Preprocessor(localPreprocessorLexer);
    localPreprocessor.setTool(this.antlrTool);
    localPreprocessor.setFilename(paramString);
    try
    {
      localPreprocessor.grammarFile(this, paramString);
    }
    catch (TokenStreamException localTokenStreamException)
    {
      this.antlrTool.toolError("Token stream error reading grammar(s):\n" + localTokenStreamException);
    }
    catch (ANTLRException localANTLRException)
    {
      this.antlrTool.toolError("error reading grammar(s):\n" + localANTLRException);
    }
  }

  public boolean verifyThatHierarchyIsComplete()
  {
    Grammar localGrammar1;
    int i = 1;
    Enumeration localEnumeration = this.symbols.elements();
    while (true)
    {
      Grammar localGrammar2;
      do
      {
        while (true)
        {
          if (!(localEnumeration.hasMoreElements()))
            break label101;
          localGrammar1 = (Grammar)localEnumeration.nextElement();
          if (localGrammar1.getSuperGrammarName() != null)
            break;
        }
        localGrammar2 = localGrammar1.getSuperGrammar();
      }
      while (localGrammar2 != null);
      this.antlrTool.toolError("grammar " + localGrammar1.getSuperGrammarName() + " not defined");
      i = 0;
      this.symbols.remove(localGrammar1.getName());
    }
    if (i == 0)
      label101: return false;
    localEnumeration = this.symbols.elements();
    while (true)
    {
      while (true)
      {
        if (!(localEnumeration.hasMoreElements()))
          break label159;
        localGrammar1 = (Grammar)localEnumeration.nextElement();
        if (localGrammar1.getSuperGrammarName() != null)
          break;
      }
      localGrammar1.setType(findRoot(localGrammar1).getName());
    }
    label159: return true;
  }

  public Tool getTool()
  {
    return this.antlrTool;
  }

  public void setTool(Tool paramTool)
  {
    this.antlrTool = paramTool;
  }
}